package sfeir.gwt.ergosoom.client.profile;

import java.util.ArrayList;
import java.util.List;

import sfeir.gwt.ergosoom.client.Messages;
import sfeir.gwt.ergosoom.client.images.ErgoImages;
import sfeir.gwt.ergosoom.client.model.Address;
import sfeir.gwt.ergosoom.client.model.Email;
import sfeir.gwt.ergosoom.client.model.NetworkItem;
import sfeir.gwt.ergosoom.client.model.Tel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class FlexComboField extends Composite implements HasChangeHandlers {
    private Messages message = GWT.create(Messages.class);
    
	public static final int PHONE = 0;
	public static final int MAIL = 1;
	public static final int ADDRESS = 2;
	public static final int WEBURL = 3;

	private final ErgoImages images = GWT.create(ErgoImages.class);

	// private FlexTable flexyTable;
	private VerticalPanel flexyTable;
	private Grid panel;
	private Image add = images.add().createImage();
	private int dataType;
	private ArrayList<Tel> tels;
	private ArrayList<Email> mails;
	private ArrayList<Address> addresses;
	private ArrayList<NetworkItem> networks;

	public FlexComboField(int type) {
	    
		Image icon = null;
		HTML title = null;
		dataType = type;
		switch (dataType) {
		case PHONE:
			icon = images.phone().createImage();
			title = new HTML(message.phone());
			tels = new ArrayList<Tel>();
			break;
		case MAIL:
			icon = images.email().createImage();
			title = new HTML(message.email());
			mails = new ArrayList<Email>();
			break;
		case ADDRESS:
			icon = images.house().createImage();
			title = new HTML(message.address());
			addresses = new ArrayList<Address>();
			break;
		case WEBURL:
			icon = images.world().createImage();
			title = new HTML(message.urls());
			networks = new ArrayList<NetworkItem>();
			break;
		default:
			break;
		}

		panel = new Grid(1, 4);
		panel.setWidget(0, 0, icon);
		panel.setWidget(0, 1, title);

		flexyTable = new VerticalPanel();// new FlexTable();
		addRow();

		panel.setWidget(0, 2, flexyTable);

		PushButton more = new PushButton(add);
		more.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				addRow();
			}
		});
		panel.setWidget(0, 3, more);

		/*
		 * Let's add some style now
		 */
		panel.getCellFormatter().setVerticalAlignment(0, 0,
				HasAlignment.ALIGN_TOP);
		panel.getCellFormatter().setVerticalAlignment(0, 1,
				HasAlignment.ALIGN_TOP);
		panel.getCellFormatter().setWidth(0, 1, "70px");
		panel.getCellFormatter().setHorizontalAlignment(0, 2,
				HasAlignment.ALIGN_LEFT);
		panel.getCellFormatter().setWidth(0, 2, "300px");
		panel.getCellFormatter().setVerticalAlignment(0, 3,
				HasAlignment.ALIGN_TOP);
		panel.getCellFormatter().setStyleName(0, 3, "pt");

		initWidget(panel);
	}

	public ArrayList<?> getDatas() {
		switch (dataType) {
		case PHONE:
			tels = new ArrayList<Tel>();
			break;
		case MAIL:
			mails = new ArrayList<Email>();
			break;
		case ADDRESS:
			addresses = new ArrayList<Address>();
			break;
		case WEBURL:
			networks = new ArrayList<NetworkItem>();
		}
		receiveData();
		switch (dataType) {
		case PHONE:
			return tels;
		case MAIL:
			return mails;
		case ADDRESS:
			return addresses;
		case WEBURL:
			return networks;
		}
		return null;
	}

	private void receiveData() {
		int length = flexyTable.getWidgetCount();
		for (int i = 0; i < length; i++) {
			HorizontalPanel hp = (HorizontalPanel) flexyTable.getWidget(i);
			int selected = ((ListBox) hp.getWidget(0)).getSelectedIndex();
			String content = ((TextBox) hp.getWidget(1)).getText();
			saveDatas(selected, content);
		}
	}

	private void saveDatas(int selected, String content) {
		if (content != null && !content.equals("")) {
			switch (dataType) {
			case PHONE:
				Tel t = new Tel();
				t.setPhoneNumber(content);
				switch (selected) {
				case 0:
					t.setType(Tel.MOBILE_LINE);
					break;
				case 1:
					t.setType(Tel.HOME_LANDLINE);
					break;
				case 2:
					t.setType(Tel.PROFESSIONNAL_LINE);
					break;
				case 3:
					t.setType(Tel.HOME_LANDLINE);
					break;
				}
				tels.add(t);
				break;
			case MAIL:
				Email m = new Email();
				m.setEmail(content);
				switch (selected) {
				case 0:
					m.setTypeEmail(Email.PERSONAL_EMAIL);
					break;
				case 1:
					m.setTypeEmail(Email.PROFESSIONNAL_EMAIL);
					break;
				case 2:
					m.setTypeEmail(Email.UNKNOWN);
					break;
				}
				mails.add(m);
				break;
			case ADDRESS:
				Address a = new Address();
				a.setFullValue(content);
				switch (selected) {
				case 0:
					a.setType(Address.PERSONAL_ADDRESS);
					break;
				case 1:
					a.setType(Address.PROFESSIONNAL_ADDRESS);
					break;
				case 2:
					a.setType(Address.DEFAULT_ADDRESS);
					break;
				}
				addresses.add(a);
				break;
			case WEBURL:
				NetworkItem n = new NetworkItem();
				n.setNetworkItemLink(content);
				switch (selected) {
				case 0:
					n.setNetworkItemType("website");
					break;
				case 1:
					n.setNetworkItemType("company");
					break;
				case 2:
					n.setNetworkItemType("blog");
					break;
				case 3:
					n.setNetworkItemType("other");
					break;
				}
				networks.add(n);
				break;
			}
		}
	}

	public void setRowsTel(List<Tel> list) {
		removeAll();
		for (Tel item : list) {
			int type = 0;
			switch (item.getType()) {
			case Tel.MOBILE_LINE:
				type = 0;
				break;
			case Tel.HOME_LANDLINE:
				type = 1;
				break;
			case Tel.PROFESSIONNAL_LINE:
				type = 2;
				break;
			default:
				type = 3;
				break;
			}
			
			addRow(type, item.getPhoneNumber());
		}
	}

	public void setRowsEmail(List<Email> list) {
		removeAll();
		for (Email item : list) {
			int type = 0;
			switch (item.getTypeEmail()) {
			case Email.PERSONAL_EMAIL:
				type = 0;
				break;
			case Email.PROFESSIONNAL_EMAIL:
				type = 1;
				break;
			default:
				type = 2;
				break;
			}
			addRow(type, item.getEmail());
		}
	}

	public void setRowsAddress(List<Address> list) {
		removeAll();
		for (Address item : list) {
			int type = 0;
			switch (item.getType()) {
			case Address.PERSONAL_ADDRESS:
				type = 0;
				break;
			case Address.PROFESSIONNAL_ADDRESS:
				type = 1;
				break;
			default:
				type = 2;
				break;
			}
			addRow(type, item.getFullValue());
		}
	}

	@SuppressWarnings("unchecked")
	public void setRows(List<?> list) {

		if (list != null && list.size() > 0) {
			if (list.get(0) instanceof Tel) {
				setRowsTel((List<Tel>) list);
			} else if (list.get(0) instanceof Email) {
				setRowsEmail((List<Email>) list);
			} else if (list.get(0) instanceof Address) {
				setRowsAddress((List<Address>) list);
			}
		}
	}

	public void removeAll() {
		flexyTable = new VerticalPanel();// new FlexTable();
		panel.setWidget(0, 2, flexyTable);
	}

	/**
	 * Add a row to the flex table.
	 */
	private void addRow() {
		addRow(null, null);
	}

	private void addRow(Integer type, String content) {

		final HorizontalPanel hp = new HorizontalPanel();

		ListBox choices = new ListBox();
		choices.setWidth("100px");

		if (dataType != WEBURL) {
			if (dataType == PHONE)
				choices.addItem(message.mobile());

			choices.addItem(message.home());
			choices.addItem(message.work());
		} else {
			choices.addItem(message.my_website());
			choices.addItem(message.my_company());
			choices.addItem(message.my_blog());
		}
		
		if (dataType != PHONE)
			choices.addItem(message.other());
		
		if (type != null) {
			choices.setSelectedIndex(type);
		}
		hp.add(choices);

		TextBox text = new TextBox();
		text.setWidth("165px");
		text.setFocus(true);
		if (content != null) {
			text.setValue(content);
		}
		hp.add(text);

		PushButton remove = new PushButton(images.delete().createImage());
		remove.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				flexyTable.remove(hp);
				if (flexyTable.getWidgetCount() == 0)
					addRow();
				if (changeReg != null)
				    changeReg.onChange(null);
			}
		});
		hp.add(remove);
		
		if (changeReg != null) {
		    text.addChangeHandler(changeReg);
		    choices.addChangeHandler(changeReg);
		}

		flexyTable.add(hp);

	}

	private ChangeHandler changeReg = null;
	
    @Override
    public HandlerRegistration addChangeHandler(ChangeHandler handler) {
        changeReg = handler;
        int length = flexyTable.getWidgetCount();
        for (int i = 0; i < length; i++) {
            HorizontalPanel hp = (HorizontalPanel) flexyTable.getWidget(i);
            ((ListBox) hp.getWidget(0)).addChangeHandler(handler);
            ((TextBox) hp.getWidget(1)).addChangeHandler(handler);          
        }
        return null;
    }
}